package com.telecom.mapper;

import com.telecom.pojo.dto.user.order.OrderMealInfoDTO;
import com.telecom.pojo.dto.user.order.OrderPageQueryRequestDTO;
import com.telecom.pojo.entity.Order;
import com.telecom.pojo.vo.admin.order.AdminOrderDetailVO;
import com.telecom.pojo.vo.admin.order.AdminOrderItemVO;
import com.telecom.pojo.vo.admin.workspace.OrderOverViewVO;
import com.telecom.pojo.vo.user.order.OrderItemVO;
import jakarta.validation.constraints.NotNull;
import org.apache.ibatis.annotations.*;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 订单表 Mapper 接口
 * </p>
 *
 * @author GWX.cz
 * @since 2025-07-31
 */
@Mapper
public interface OrderMapper {

    /**
     * 管理端订单分页查询
     * 
     * @param idOrUsername 订单ID或用户名（可选）
     * @param status 状态（可选）
     * @return 订单列表
     */
    List<AdminOrderItemVO> selectAdminOrderPage(@Param("idOrUsername") String idOrUsername,
                                                @Param("status") Integer status);


    /**
     * 根据订单号查询订单
     * 
     * @param orderNumber 订单号
     * @return 订单信息
     */
    @Select("select * from `order` where order_number = #{orderNumber}")
    Order selectByOrderNumber(@Param("orderNumber") String orderNumber);

    /**
     * 更新订单取餐状态
     * 
     * @param orderNumber 订单号
     * @param pickupStatus 取餐状态
     * @return 影响行数
     */
    int updatePickupStatusByOrderNumber(@Param("orderNumber") String orderNumber,
                                       @Param("pickupStatus") Integer pickupStatus);

    /**
     * 根据订单ID更新订单状态
     * 
     * @param id 订单ID
     * @param payStatus 支付状态
     * @param pickupStatus 取餐状态
     * @return 影响行数
     */
    int updateOrderStatus(@Param("id") Long id,
                         @Param("payStatus") Integer payStatus,
                         @Param("pickupStatus") Integer pickupStatus);

    /**
     * 根据订单ID查询订单
     * 
     * @param id 订单ID
     * @return 订单信息
     */
    @Select("select * from `order` where id = #{id}")
    Order selectById(@Param("id") Long id);

    /**
     * 根据订单ID查询订单详情（包含用户昵称和套餐名称）
     * 
     * @param id 订单ID
     * @return 订单详情
     */
    AdminOrderDetailVO selectOrderDetailById(@Param("id") Long id);

    // ==================== 工作台统计方法 ====================
    
    /**
     * 统计今日套餐订单数（已支付的套餐订单）
     * 
     * @return 今日套餐订单数
     */
    Integer countTodayMealOrders();
    
    /**
     * 统计今日营业额
     * 
     * @return 今日营业额
     */
    BigDecimal getTodayTurnover();
    
    /**
     * 计算订单满意率
     * 
     * @return 包含总订单数和满意订单数的Map
     */
    Map<String, Object> getOrderSatisfactionRate();
    
    /**
     * 按餐型统计某一天订单概览数据
     * 
     * @return 订单概览列表
     */
    List<OrderOverViewVO> getOrderOverviewByMealType(LocalDate date);

    /**
     * 创建新订单
     * @param order
     * @return 受影响的行数
     */
    int insert(Order order);

    /**
     * 更新订单支付状态、取餐方式和备注
     * @param id 订单ID
     * @param payStatus 支付状态
     * @param totalAmount 总金额
     * @param diningType 取餐方式
     * @param remark 备注信息
     */
    void updatePayStatusAndOrderInfo(@Param("id") Long id, 
                                   @Param("payStatus") int payStatus, 
                                   @Param("totalAmount") BigDecimal totalAmount,
                                   @Param("diningType") Integer diningType,
                                   @Param("remark") String remark);

    /**
     * 用户用餐评价
     * @param id
     * @param isSatisfied
     */
    @Update("update `order` set is_satisfied = #{isSatisfied}, update_time = NOW() where id = #{id}")
    void updateComment(long id, boolean isSatisfied);

    /**
     * 根据条件查询用户订单
     * @param userId 用户ID
     * @param status 订单状态
     * @return
     */
    List<OrderMealInfoDTO> userSelectPageByCondition(@Param("userId") Long userId, @Param("status") Integer status);

    /**
     * 根据支付状态和创建时间查询订单（用于处理超时订单）
     * @param payStatus 支付状态
     * @param createTime 创建时间
     * @return 订单列表
     */
    @Select("SELECT * FROM `order` WHERE pay_status = #{payStatus} AND create_time < #{createTime}")
    List<Order> getByPayStatusAndCreateTimeLT(@Param("payStatus") Integer payStatus, @Param("createTime") LocalDateTime createTime);
}
